package cn.da.shuai.cool.system.service.service.impl;

import cn.da.shuai.cool.mybatis.service.impl.CoolServiceImpl;
import cn.da.shuai.cool.redis.service.RedisService;
import cn.da.shuai.cool.system.service.mapper.CoolUserOnlineMapper;
import cn.da.shuai.cool.system.model.entity.online.CoolUserOnline;
import cn.da.shuai.cool.system.service.service.ICoolUserOnlineService;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;

/**
 * 在线用户服务实现类
 */
@Service
public class CoolUserOnlineServiceImpl extends CoolServiceImpl<CoolUserOnlineMapper, CoolUserOnline> implements ICoolUserOnlineService {

    @Autowired
    private RedisService redisService;

    /**
     * 在线用户缓存前缀
     */
    private static final String ONLINE_PREFIX = "sys_user_online:";

    @Override
    public CoolUserOnline selectOnlineById(String sessionId) {
        CoolUserOnline userOnline = redisService.getObject(ONLINE_PREFIX + sessionId, CoolUserOnline.class);
        if (userOnline == null) {
            userOnline = this.getById(sessionId);
        }
        return userOnline;
    }

    @Override
    public void deleteOnlineById(String sessionId) {
        CoolUserOnline userOnline = selectOnlineById(sessionId);
        if (userOnline != null) {
            this.removeById(sessionId);
            redisService.delete(ONLINE_PREFIX + sessionId);
        }
    }

    @Override
    public void batchDeleteOnline(List<String> sessions) {
        for (String sessionId : sessions) {
            CoolUserOnline userOnline = selectOnlineById(sessionId);
            if (userOnline != null) {
                this.removeById(sessionId);
                redisService.delete(ONLINE_PREFIX + sessionId);
            }
        }
    }

    @Override
    public void saveOnline(CoolUserOnline online) {
        this.saveOrUpdate(online);
        redisService.set(ONLINE_PREFIX + online.getSessionId(), online);
    }

    @Override
    public List<CoolUserOnline> selectUserOnlineList(CoolUserOnline userOnline) {
        LambdaQueryWrapper<CoolUserOnline> lqw = new LambdaQueryWrapper<>();
        lqw.like(StrUtil.isNotBlank(userOnline.getIpaddr()), CoolUserOnline::getIpaddr, userOnline.getIpaddr())
           .eq(StrUtil.isNotBlank(userOnline.getStatus()), CoolUserOnline::getStatus, userOnline.getStatus())
           .like(StrUtil.isNotBlank(userOnline.getLoginName()), CoolUserOnline::getLoginName, userOnline.getLoginName());
        return this.list(lqw);
    }

    @Override
    public Page<CoolUserOnline> selectUserOnlinePage(CoolUserOnline userOnline, Page<CoolUserOnline> page) {
        LambdaQueryWrapper<CoolUserOnline> lqw = new LambdaQueryWrapper<>();
        lqw.like(StrUtil.isNotBlank(userOnline.getIpaddr()), CoolUserOnline::getIpaddr, userOnline.getIpaddr())
           .eq(StrUtil.isNotBlank(userOnline.getStatus()), CoolUserOnline::getStatus, userOnline.getStatus())
           .like(StrUtil.isNotBlank(userOnline.getLoginName()), CoolUserOnline::getLoginName, userOnline.getLoginName());
        return this.page(page, lqw);
    }

    @Override
    public void forceLogout(String sessionId) {
        deleteOnlineById(sessionId);
    }

    @Override
    public List<CoolUserOnline> selectOnlineByExpired(Date expiredDate) {
        LocalDateTime expiredDateTime = expiredDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        LambdaQueryWrapper<CoolUserOnline> lqw = new LambdaQueryWrapper<>();
        lqw.lt(CoolUserOnline::getLastAccessTime, expiredDateTime);
        return this.list(lqw);
    }
}